using Abc.Core;

using Furion;

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

using Serilog;

using System.Collections.Generic;

using Tool;

using UEditorNetCore;

namespace Web.Core
{
    [AppStartup(700)]
    public sealed class WebCoreStartup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddLogging(loggingBuilder =>
            //{
            //    loggingBuilder.ClearProviders();
            //    loggingBuilder.AddSerilog(dispose: true);
            //});




            services.AddConfigurableOptions<AppInfoOptions>();//选项不同于配置，需在应用启动时注册

            // 注册 JWT 授权
            // services.AddJWTAuthorization<JWTAuthorizationHandler>();
            // JWT 和 Cookies 同时授权
            //services.AddJwt<JwtHandler>(options =>
            //{
            //    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            //    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            //})

            #region ActionFilter 授权验证

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
           //后台
           .AddCookie(AuthorizeType.AdminAuthenticationScheme, options =>
            {
                //options.AccessDeniedPath = "/Account/Forbidden";
                options.LoginPath = "/HtAdmin/Account/Login";
                options.LogoutPath = "/HtAdmin/Account/LoginOut";
            });
            ////  用户后台
            //.AddCookie(AuthorizeType.ConsumerAuthenticationScheme, options =>
            //{
            //    //options.AccessDeniedPath = "/Account/Forbidden";
            //    options.LoginPath = "/u/Account/Login";
            //    options.LogoutPath = "/u/Account/LoginOut";
            //});

            #endregion ActionFilter 授权验证

            #region 授权

            //services.AddAuthorization(options =>
            //{
            //    options.AddPolicy(AuthorizeType.AdminAuthenticationScheme, policy =>
            //        policy.Requirements.Add(new PermissionCheckPolicyRequirement()));
            //});
            //services.AddSingleton<IAuthorizationHandler, PermissionCheckPolicyHandler>();

            #endregion 授权

            services.AddCorsAccessor();//添加跨域配置
            services.AddMemoryCache();//添加内存缓存

            services.AddUEditorService();//添加Ueditor
            services.AddSession(); //Session

            services.AddRazorPages();
            services.AddControllers();
            services.AddControllersWithViews(options =>
            {
                //Web 拦截器
                options.Filters.Add(new LogFilterAttribute());
                //此处注册全局 输入验证
                options.Filters.Add(new ValidateEntityFilterAttribute(ValidationEntityType.All, isMvcReutrnMultipleErrors: true));
                //此处 注册全局   防止重复提交 特性(影响性能,有1~10毫秒左右影响)
                options.Filters.Add(new PreventSpamFilterAttribute(httpAccessInterval: 30));
            })
                .AddRazorRuntimeCompilation()
                .AddDataValidation()
                .AddInjectWithUnifyResult<WebRESTfulResultProvider>()
                .AddNewtonsoftJson(options =>
                 {
                     options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                     options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;//不循环引用
                     options.SerializerSettings.ContractResolver = new DefaultContractResolver()
                     {
                         NamingStrategy = new DefaultNamingStrategy()
                     };
                 }).AddJsonOptions(options =>
                 {
                     options.JsonSerializerOptions.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All);
                 }); ;
            //.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver()
            //{
            //    NamingStrategy = new DefaultNamingStrategy()
            //})
            //注册 API过滤器
            //services.AddScoped<ApiActionFilterAttribute>();

            services.AddTaskScheduler();

            services.AddPBKDF2EncryptionOptions();//PBKDF2
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseCustomStaticFile();//自定义资源文件
            //app.UseStaticFiles(new StaticFileOptions
            //{
            //    //FileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()),
            //    //设置不限制content-type 该设置可以下载所有类型的文件，但是不建议这么设置，因为不安全
            //    //ServeUnknownFileTypes = true
            //    //下面设置可以下载apk和nupkg类型的文件
            //    ContentTypeProvider = new FileExtensionContentTypeProvider(new Dictionary<string, string>
            //    {
            //      { ".apk","application/vnd.android.package-archive"},
            //      //{ ".nupkg","application/zip"}
            //    })
            //});
            app.UseStaticFiles();
            app.UseSerilogRequestLogging();    // 必须在 UseStaticFiles 和 UseRouting 之间
            app.UseRouting();
            app.UseCorsAccessor();

            app.UseSession();

            app.UseAuthentication();//身份认证。
            app.UseAuthorization();//授权

            app.UseInject();//注入基础中间件，带swagger

            //原生的Context中并没有包含客户端的IP地址跟端口号。
            //我们需要手动的在Nuget中引入
            //"Microsoft.AspNetCore.HttpOverrides": "1.0.0" 这个包
            app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();

                endpoints.MapAreaControllerRoute(
                    name: "areas", "areas",
                    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

                endpoints.MapControllerRoute(
                    name: "areas",
                    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
                );
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}